home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / demos / video / vidpaint.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  23KB  |  1,052 lines

  1. /*
  2.  * Copyright (C) 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17.     
  18. /*
  19.  *  File:    vidpaint.c
  20.  *
  21.  *        uses much of 4Dgifts example, 
  22.  *            contcapt.c for much of VL code.
  23.  *        
  24.  *        last modified 2/22/94 atang
  25.  *                  4/6/94  atang even field capture
  26.  * 
  27.  */
  28.  
  29. #include <sys/types.h>
  30. #include <sys/stat.h>
  31. #include <fcntl.h>
  32. #include <stdlib.h>
  33.  
  34. #include <stdio.h>
  35. #include <string.h>
  36. #include <malloc.h>
  37. #include <getopt.h>
  38. #include <sys/time.h>
  39. #include <gl/gl.h>
  40. #include <gl/device.h>
  41. #include <gl/image.h>
  42.  
  43. #include <vl/vl.h>
  44.  
  45. #define VL_PACKING_INVALID    -1
  46. #define Debug            if (debug) printf
  47. #define TIME_ARRAY_SIZE        400    /* MUST be divisible by 5! */
  48. #define TIME_GRANULARITY    1000
  49. #define PAINT            0
  50. #define COMPOUND        1
  51.  
  52.  
  53. void         ProcessEvent(VLServer, VLEvent *, void *);
  54. void        ProcessGlEvent(int, void *);
  55. int        pause(void);
  56. void        exitcapture(void);
  57.  
  58. /*
  59.  *  Global variables
  60.  */
  61. char *cmdargs = "b:c:dDeFg:hi:mn:o:p:r:tv:wz:";
  62. char *usage_m =
  63.     "usage: %s %s\n"
  64.     "where arguments may be:\n"
  65.     "    -b n    use n buffers\n"
  66.     "    -c n    capture n frames\n"
  67.     "    -d    turn off double buffer mode\n"
  68.     "    -D    turn on debug mode (displays more information)\n"
  69.     "    -e    turn OFF even fields only mode\n"
  70.     "    -F    specifies field (or non-interleaved) mode\n"
  71.     "    -i n    report statistics every n frames\n"
  72.     "    -m    monochrome input\n"
  73.     "    -n n    device number n \n"
  74.     "    -o n     video output source to use (depends on hardware)\n"
  75.     "    -p n    set win position (1=upperLHS,0=lowerLHS(default))\n"
  76.     "    -r n    set frame rate to n\n"
  77.     "    -t    turn on timing statistics gathering\n"
  78.     "    -v n     video input source to use (depends on hardware)\n"
  79.     "    -w    32 bit 'wide' RGB pixels\n"
  80.     "    -h    this help message\n"
  81. ;
  82.  
  83. char         *_progName;
  84. char         *deviceName;
  85. int        devicenum = -1;
  86. int        ev1num = -1;
  87. int        buffers = 2;
  88. int        packing = VL_PACKING_INVALID;
  89. int        totalCount = 10000000;
  90. int        debug = 0;
  91. int        double_buffer = 1;
  92. int        fast = 0;
  93. int        fieldmode = 0;
  94. int        evenfields = 1;
  95. int        frameCount;
  96. int        frameInterval = -1;
  97. int        framenumber = 0;
  98. int        lasttime = 0;
  99. int        rate = 0;
  100. int        secs;
  101. int        time_array[TIME_ARRAY_SIZE];
  102. int        time_on = 0;
  103. int        xsize = 0;
  104. int        ysize = 0;
  105. int        zoom_num = 1, zoom_denom = 4; /* set zoom to 1/4 always */
  106. struct timeval    tv_save;
  107. VLPath        vlPath;
  108. VLServer    vlSvr;
  109. VLNode        drn;
  110. VLNode        src;
  111. VLBuffer    transferBuf;
  112. int        mywinposition = 0; 
  113. int        effecttype = 0;
  114. int        backcolor = 0;
  115. int        input_timing;
  116. int        vin = VL_ANY;
  117. int        vout = VL_ANY;
  118. int        vinflag = 0;
  119. int        voutflag = 0;
  120. int        yzoommult = 2;
  121. int        rzoom = 1;
  122.  
  123. long sizex, sizey;
  124. short dev, val;
  125. int active=TRUE;
  126. long win;
  127. int menu;
  128. short x=0;
  129. short y=0;
  130. short val, leftmousedown;
  131. int doalpha = 0;
  132. int pixscale = 1;
  133. long orgx, orgy;
  134.  
  135. #define brushx 15
  136. #define brushy 15
  137. unsigned long alpha = 0xff000000;
  138. unsigned long *getframe;
  139. unsigned long *drawframe;
  140. unsigned long brush[brushx][brushy];
  141. int drawcolors = 0; /* plain, funky, negative */
  142.  
  143.  
  144. prepare_window(){
  145.     RGBmode();
  146.     gconfig();
  147.     cpack(0x00000000);
  148.     clear();
  149.     blendfunction(BF_SA, BF_MSA);  
  150.     qdevice(INPUTCHANGE);
  151.     qdevice(REDRAW);
  152.     qdevice(ESCKEY);
  153.     qdevice(WINQUIT);
  154.     qdevice(WINSHUT);
  155.     qdevice(LEFTMOUSE);
  156.     qdevice(MIDDLEMOUSE);
  157.     qdevice(RIGHTMOUSE);
  158.     qdevice(DKEY);
  159.     qdevice(CKEY);
  160.     qdevice(QKEY);
  161.     qdevice(SKEY);
  162.  
  163.     pixmode(PM_TTOB, 1);
  164. }
  165.  
  166. initialize() {
  167.  
  168.     int i,j;
  169.     short red,green,blue;
  170.     int vidx,vidy; /* input video size */
  171.  
  172.     if ((input_timing == VL_TIMING_625_SQ_PIX) || 
  173.     (input_timing == VL_TIMING_625_CCIR601) ||
  174.     (input_timing == VL_TIMING_625_4FSC))
  175.     {/* PAL */
  176.     vidx = 768;
  177.     vidy = 576;
  178.     }else
  179.     {/* NTSC */
  180.     vidx = 640;
  181.     vidy = 486;
  182.     }
  183.  
  184.     if (mywinposition == 1)
  185.     {
  186.       prefposition((long)0, (long)(vidx+10), (long)(1023-vidy), (long)1023); 
  187.     }else /* lower left */
  188.     {
  189.       prefposition ((long)0, (long)(vidx+10), (long)0, (long)(vidy)); 
  190.     }
  191.  
  192.     win=winopen("Video Paint");
  193.  
  194.     prepare_window();
  195.  
  196.     getsize(&sizex, &sizey);
  197.     zbuffer(TRUE);
  198.     lsetdepth(0x00, 0x7fffff);
  199.     menu = defpup("Opaque | 25 Pcnt  Blend | 6.25 Pcnt Blend | 1x | 2x | 4x | Plain | Funky | Negative | Paint | Multiple | Background Colors | Quit");
  200.  
  201.     return(0);
  202. }
  203.  
  204.  
  205. /* code for reading from disk (not currently called) */
  206. read_img()
  207. {
  208. }
  209.  
  210. draw_scene(short x, short y) {
  211.     
  212.     int i,j, xp, yp;
  213.     unsigned long *prgb;
  214.     unsigned long *dprgb;
  215.     unsigned char *pval;
  216.     short gotalpha,red,blue,green;
  217.  
  218. /* the alpha code puts alpha values that i want into the */
  219. /* array returned by VL, but this is inefficient */
  220.  
  221.     for (j=0;j<ysize;j++){
  222.         prgb = &getframe[0] + ((ysize - 1) - j)*xsize;
  223.         for (i=0;i<xsize;i++)
  224.       {
  225.        pval = (unsigned char *)(prgb+i);
  226.        gotalpha = *pval++;
  227.        blue = *pval++;
  228.        green = *pval++;
  229.        red = *pval++;
  230.        switch (drawcolors) {
  231.         case 0:
  232.         *(prgb+i)=red|(green<<8)|(blue<<16)|alpha;
  233.         break;
  234.         case 1: 
  235.         *(prgb+i)=red|(green<<11)|(blue<<19)|alpha;
  236.         break;
  237.         case 2:
  238.         *(prgb+i)=(255-red)|((255-green)<<8)|((255-blue)<<16)|alpha;
  239.         break;
  240.         };/* end switch */
  241.           }/* end for i */
  242.       }/* end for j*/
  243.  
  244.     switch (rzoom) /* adjust zoom factors - yzoommult = 2.0 if evenfields*/
  245.     {
  246.     case 1: /* 1x */
  247.     rectzoom(1.0, 1.0*yzoommult);
  248.     break;
  249.     case 2: /* 2x */
  250.     rectzoom(2.0, 2.0*yzoommult);
  251.     break;
  252.     case 4: /* 4x */
  253.     rectzoom(4.0, 4.0*yzoommult);
  254.     break;
  255.     }
  256.  
  257.    switch (effecttype)
  258.    {
  259.     case COMPOUND:
  260.     xp = 20;
  261.     yp = 20;
  262.     for (i = 0; i<3; i++)
  263.     {
  264.         for (j = 0; j<3; j++)
  265.         {
  266.         lrectwrite(i*xsize+i*xp+64, j*ysize*yzoommult+j*yp+48, 
  267.              (i+1)*xsize-1+i*xp+64,(j+1)*ysize-1+j*yp+48,
  268.               &getframe[0]); 
  269.         }
  270.     }
  271.     break;
  272.     case PAINT:
  273.     default:
  274.     lrectwrite(x, y, xsize-1+x, ysize-1+y, &getframe[0]);
  275.     break;
  276.     } 
  277. }
  278.  
  279.  
  280. void
  281. initStatistics(void)
  282. {
  283.     if (!debug) return;
  284.     gettimeofday(&tv_save);
  285. }
  286.  
  287. void
  288. reportStatistics(void)
  289. {
  290.     double rate;
  291.     struct timeval tv;
  292.     int delta_t;
  293.  
  294.    /* Delta_t in microseconds */
  295.     delta_t = (tv.tv_sec*1000 + tv.tv_usec/1000) -
  296.           (tv_save.tv_sec*1000 + tv_save.tv_usec/1000);
  297.     
  298.     rate = frameCount*1000.0/delta_t;
  299.     
  300.     printf("got %5.2f frames/sec\n", rate);
  301.     tv_save.tv_sec = tv.tv_sec;
  302.     tv_save.tv_usec = tv.tv_usec;
  303.  
  304. }
  305.  
  306. char *
  307. packing_name (int packtype)
  308. {
  309.     switch (packtype) 
  310.     {
  311.     case VL_PACKING_RGB_8:    
  312.         return "RGB";
  313.     break;
  314.     
  315.         case VL_PACKING_RGBA_8:   
  316.         return "RGBA";
  317.     break;
  318.     
  319.     case VL_PACKING_RBG_323:   
  320.         return "Starter Video RGB8";
  321.     break;
  322.     
  323.     case VL_PACKING_RGB_332_P:    
  324.         return "RGB332";
  325.     break;
  326.     
  327.     case VL_PACKING_Y_8_P: 
  328.         return "8 Bit Greyscale";
  329.     break;
  330.     
  331.     default:        
  332.         return "???";
  333.     break;
  334.     }
  335. }
  336.  
  337. getcmdargs(int argc, char **argv)
  338. {
  339.     int c;
  340.     int len, xlen, ylen;
  341.     char numbuf[5];
  342.     char *xloc;
  343.    
  344.     while ((c = getopt(argc, argv, cmdargs)) != EOF) 
  345.     {
  346.     switch (c) 
  347.     {
  348.  
  349.         case 'b':
  350.         buffers = atoi(optarg);
  351.         break;
  352.     
  353.         case 'c':
  354.         totalCount = atoi(optarg);
  355.         break;
  356.     
  357.         case 'D':
  358.         debug = 1;
  359.         break;
  360.     
  361.         case 'd':
  362.         double_buffer = 0;
  363.         break;
  364.     
  365.         case 'e':
  366.         evenfields = 0;
  367.         yzoommult = 1;
  368.         break;
  369.  
  370.         case 'f':
  371.         fast = 1;
  372.         break;
  373.     
  374.         case 'F':
  375.         fieldmode = 1;
  376.         break;
  377.     
  378.         case 'g':
  379.         len = strlen(optarg);
  380.         xloc = strchr(optarg, 'x');
  381.         if (!xloc) 
  382.         {
  383.             printf("Error: invalid geometry format, using default size\n");
  384.             break;
  385.         }
  386.         xlen = len - strlen(xloc);
  387.         if (xlen < 1 || xlen > 4) 
  388.         {
  389.             printf("Error: invalid x size, using default size\n");
  390.             break;
  391.         }
  392.         strncpy(numbuf, optarg, xlen);
  393.         xsize = atoi(numbuf);
  394.     
  395.         ylen = len - xlen -1;
  396.         if (ylen < 1 || ylen > 4) 
  397.         {
  398.             printf("Error: invalid y size, using default size\n");
  399.             break;
  400.         }
  401.         strncpy(numbuf, &optarg[xlen + 1], ylen);
  402.         ysize = atoi(numbuf);
  403.         break;
  404.     
  405.         case 'i':
  406.         frameInterval = atoi(optarg);
  407.         printf("frameInterval = %d\n", frameInterval);
  408.         break;
  409.         
  410.         case 'm':
  411.         packing = VL_PACKING_Y_8_P;
  412.         break;
  413.     
  414.         case 'n':
  415.         devicenum = atoi(optarg);
  416.         printf("User specified device number: %d\n", devicenum);
  417.         break;
  418.  
  419.         case 'o':
  420.         vout = atoi(optarg);
  421.         voutflag = 1;
  422.         Debug ("video output = %d\n", vout);
  423.         break;
  424.     
  425.             case 'p':
  426.         mywinposition = atoi (optarg);
  427.         break;
  428.  
  429.         case 'r':
  430.         rate = atoi(optarg);
  431.         break;
  432.     
  433.         case 't':
  434.         time_on = 1;
  435.         break;
  436.     
  437.         case 'v':
  438.         vin = atoi(optarg);
  439.         vinflag = 1;
  440.         Debug ("video input = %d\n", vin);
  441.         break;
  442.     
  443.         case 'w':
  444.         packing = VL_PACKING_RGB_8;
  445.         break;
  446.         
  447.         case 'z': /* we're only supporting z 1/4 for now */
  448.         break;
  449.         
  450.         case 'h':
  451.         default:
  452.         fprintf(stderr, usage_m, _progName, cmdargs);
  453.         exit(0);
  454.         break;
  455.     }
  456.     }
  457. }
  458.  
  459. main(int argc, char **argv)
  460. {
  461.     VLDevList devlist;
  462.     char *deviceName;
  463.     char window_name[128];
  464.     char *xloc;
  465.     long win;
  466.     int c,i;
  467.     int len, xlen, ylen;
  468.     VLControlValue val;
  469.  
  470.  
  471.     _progName = argv[0];
  472.     getcmdargs(argc, argv);
  473.  
  474.     if (time_on)
  475.     for (c = 0; c < 1000; c++)
  476.         time_array[c] = 0;
  477.  
  478.     if (!(vlSvr = vlOpenVideo(""))) {
  479.     printf("couldn't open video\n");
  480.     exit(1);
  481.     }
  482.  
  483.     if (vlGetDeviceList(vlSvr, &devlist) < 0) {
  484.     printf("error getting device list: %s\n",vlStrError(vlErrno));
  485.     exit(1);
  486.     }
  487.     
  488.     /* find ev1 */
  489.     for (i=0; i<devlist.numDevices; i++) 
  490.         if (strcmp(devlist.devices[i].name,"ev1") == 0)
  491.         ev1num = i;
  492.     if ( (ev1num == -1) /* no ev1 found ... OR ...*/
  493.     || ((devicenum != -1) && (devicenum != ev1num))) /* non ev1 specified*/
  494.     {
  495.       printf("This program requires 'ev1' hardware.\a\n");
  496.       if (ev1num != -1) 
  497.     printf("Use device number '%d', or use the default mode\n",ev1num);
  498.       exit(1);
  499.     }else
  500.     {
  501.       printf("Setting device number to %d\n", ev1num);
  502.       devicenum = ev1num; /* allow default to work */
  503.     }
  504.  
  505.     /* Set up a source node on the specified video source */
  506.     if (vinflag == 0)
  507.     src = vlGetNode(vlSvr, VL_SRC, VL_VIDEO, VL_ANY);
  508.     else
  509.     src = vlGetNode(vlSvr, VL_SRC, VL_VIDEO, vin);
  510.     
  511.     /* Set up a drain node in memory */
  512.     if (voutflag == 0)
  513.     drn = vlGetNode(vlSvr, VL_DRN, VL_MEM, VL_ANY);
  514.     else
  515.     drn = vlGetNode(vlSvr, VL_DRN, VL_MEM, vout);
  516.  
  517.     if ((vlPath = vlCreatePath(vlSvr, devicenum, src, drn)) < 0)
  518.     {
  519.         vlPerror("vlCreatePath");
  520.         exit(1);
  521.     }
  522.  
  523.     if (vlSetupPaths(vlSvr, (VLPathList)&vlPath, 1, VL_SHARE, VL_SHARE) < 0){
  524.     printf ("could not setup a vid to mem path\n");
  525.     exit(1);
  526.     }
  527.  
  528.     /* get the current input timing */
  529.     vlGetControl(vlSvr, vlPath, src, VL_TIMING, &val);
  530.     input_timing = val.intVal;
  531.  
  532.     /* get the name of the device we're using */
  533.     deviceName = devlist.devices[devicenum].name;
  534.     printf("Using device %d (%s)\n", devicenum, deviceName);
  535.  
  536.     val.fractVal.numerator = zoom_num;
  537.     val.fractVal.denominator = zoom_denom;
  538.     vlSetControl(vlSvr, vlPath, drn, VL_ZOOM, &val);
  539.  
  540.      /* Set the frame rate */
  541.     if (rate) 
  542.     {
  543.     val.intVal = rate;
  544.     vlSetControl(vlSvr, vlPath, src, VL_RATE, &val);
  545.     }
  546.     vlGetControl(vlSvr, vlPath, src, VL_RATE, &val);
  547.     Debug("frame rate = %d\n", val.intVal);
  548.  
  549.     /* 
  550.      * Specify what vlPath-related events we want to receive.
  551.      * In this example we only want transfer complete events.
  552.      */
  553.     vlSelectEvents(vlSvr, vlPath, VLTransferCompleteMask|VLTransferFailedMask);
  554.  
  555.     /* Set up for even frame capture */
  556.     if (evenfields) 
  557.     {
  558.     val.intVal = VL_CAPTURE_EVEN_FIELDS;
  559.     if (vlSetControl(vlSvr, vlPath, drn, VL_CAP_TYPE, &val) < 0)
  560.         vlPerror("Seting VL_PACKING");
  561.         
  562.     /* Make sure non-interleaved capture is supported by the harware */
  563.     if (vlGetControl(vlSvr, vlPath, drn, VL_CAP_TYPE, &val) < 0)
  564.         vlPerror("Geting VL_PACKING");
  565.     if (val.intVal != VL_CAPTURE_EVEN_FIELDS)
  566.         fprintf(stderr,"Capture type not set to EVEN_FIELDS: %d\n",
  567.         val.intVal);
  568.     Debug("Field (even) mode\n");
  569.     }
  570.  
  571.     /* Set up for non-interleaved frame capture */
  572.     if (fieldmode) 
  573.     {
  574.     val.intVal = VL_CAPTURE_NONINTERLEAVED;
  575.     if (vlSetControl(vlSvr, vlPath, drn, VL_CAP_TYPE, &val) < 0)
  576.         vlPerror("Seting VL_PACKING");
  577.         
  578.     /* Make sure non-interleaved capture is supported by the harware */
  579.     if (vlGetControl(vlSvr, vlPath, drn, VL_CAP_TYPE, &val) < 0)
  580.         vlPerror("Geting VL_PACKING");
  581.     if (val.intVal != VL_CAPTURE_NONINTERLEAVED)
  582.         fprintf(stderr,"Capture type not set to NONINTERLEAVED: %d\n",
  583.         val.intVal);
  584.     Debug("Field (non-interleaved) mode\n");
  585.     }
  586.  
  587.     /* Set the video geometry */
  588.     if (xsize) {
  589.     val.xyVal.x = xsize;
  590.     val.xyVal.y = ysize;
  591.     vlSetControl(vlSvr, vlPath, drn, VL_SIZE, &val);
  592.     }
  593.     vlGetControl(vlSvr, vlPath, drn, VL_SIZE, &val);
  594.     xsize = val.xyVal.x;
  595.     ysize = val.xyVal.y;
  596.     drawframe = (unsigned long *)malloc((ysize*xsize)*(sizeof(unsigned long)));
  597.     if (evenfields)
  598.     ysize = ysize / 2;
  599.     Debug("pre adjusted size %dx%d\n", xsize, ysize);
  600.     if (ysize == 243){
  601.     ysize = ysize - 3;
  602.     }
  603.     if (ysize == 121){
  604.     ysize = ysize - 1;
  605.     }
  606.     val.xyVal.x = xsize;
  607.     val.xyVal.y = ysize;
  608.     vlSetControl(vlSvr, vlPath, drn, VL_SIZE, &val);
  609.     Debug("grabbing size %dx%d\n", xsize, ysize);
  610.  
  611.    /* Set the packing type for the video board */
  612.     if (packing != VL_PACKING_INVALID)
  613.     {
  614.     val.intVal = packing;
  615.     if (vlSetControl(vlSvr, vlPath, drn, VL_PACKING, &val) < 0)
  616.         vlPerror("Getting VL_PACKING");
  617.     }
  618.     
  619.     /* Set the graphics to the same packing as the video board */
  620.     vlGetControl(vlSvr, vlPath, drn, VL_PACKING, &val);
  621.     packing = val.intVal;
  622.     switch (val.intVal)
  623.     {
  624.     case VL_PACKING_Y_8_P:
  625.     /*
  626.      * XXX -gordo
  627.      *  this needs to restore the colormap
  628.      */
  629.         {
  630.         int i;
  631.             
  632.         /* Use colormap mode for greyscale */
  633.         cmode();            
  634.         for (i = 0; i < 256; i++)
  635.             mapcolor(i, i, i, i);
  636.         pixmode(PM_SIZE, 8);    /* Pixels are 8 bit Greyscale */
  637.         gconfig();      /* Reconfigure graphics */
  638.         }
  639.     break;
  640.     
  641.     case VL_PACKING_RGB_332_P:
  642.         pixmode(PM_SIZE, 9);    /* Pixels are 8 bit RGB */
  643.     break;
  644.     
  645.     case VL_PACKING_RBG_323:
  646.         pixmode(PM_SIZE, 8);
  647.     break;
  648.     
  649.     /* Unknown packing type, use RGB as the default */
  650.     default:        
  651.         packing = val.intVal = VL_PACKING_RGB_8;
  652.         if (vlSetControl(vlSvr, vlPath, drn, VL_PACKING, &val) < 0)
  653.         vlPerror("Setting RGB");
  654.         vlGetControl(vlSvr, vlPath, drn, VL_PACKING, &val);
  655.         Debug("packing type now is %s\n", packing_name(val.intVal));
  656.         if (val.intVal != packing)
  657.         {
  658.         fprintf(stderr, "%s: Error, could not set Packing to %s", _progName,
  659.             packing_name (packing));
  660.         exit(1);
  661.         }
  662.         /*
  663.          * There is no break here intentionally... the packing should
  664.          * now be VL_PACKING_RGB, and thus should fall through...
  665.          */
  666.     case VL_PACKING_RGB_8:
  667.     case VL_PACKING_RGBA_8:
  668.     break;
  669.     }
  670.  
  671.  
  672.     initialize();
  673.     getorigin(&orgx, &orgy);
  674.     leftmousedown = 0;
  675.  
  676.     /* Set up the ring buffer for data transfer */
  677.     transferBuf = vlCreateBuffer(vlSvr, vlPath, drn, buffers);
  678.     
  679.     /* Associate the ring buffer with the path */
  680.     vlRegisterBuffer(vlSvr, vlPath, drn, transferBuf);
  681.  
  682.     /* Set ProcessEvent() as the callback for a transfer complete event */
  683.     vlAddCallback(vlSvr, vlPath, VLTransferCompleteMask|VLTransferFailedMask, 
  684.             ProcessEvent, NULL);
  685.  
  686.     vlRegisterHandler(vlSvr, qgetfd(), (VLEventHandler)ProcessGlEvent,
  687.               (VLPendingFunc) qtest, (void *)win);
  688.  
  689.     if (vlBeginTransfer(vlSvr, vlPath, 0, NULL) < 0)
  690.     {
  691.     vlPerror("vlBeginTransfer");
  692.     exit(1);
  693.     }
  694.  
  695.     initStatistics();
  696.  
  697.     /* event loop */
  698.  
  699.  
  700.     vlMainLoop();
  701.  
  702. }
  703. void
  704. ProcessEvent(VLServer svr, VLEvent *ev, void *data)
  705. {
  706.     int count;
  707.     static int frameNum;
  708.     static ulong lasttime = -1;
  709.     static ulong lastsec;
  710.     int timeDiff;
  711.     DMediaInfo *dmInfo;
  712.     VLInfoPtr info;
  713.     char *dataPtr;
  714.  
  715.    /* Display the frame rate at a user specified interval */
  716.     if (frameInterval > 0 && frameCount > frameInterval)
  717.     {
  718.     reportStatistics();
  719.     frameCount = 0;
  720.     }
  721.  
  722.     switch (ev->reason)
  723.     {
  724.     case VLTransferComplete:
  725.     framenumber++;
  726.  
  727.     /* Get a pointer to the most recently captured frame */
  728.     info = vlGetLatestValid(svr, transferBuf);
  729.     if (!info)
  730.         break;
  731.  
  732.         /* Get the valid video data from that frame */
  733.     dataPtr = vlGetActiveRegion(svr, transferBuf, info);
  734.  
  735.     if (time_on)
  736.     {
  737.         dmInfo = vlGetDMediaInfo(svr, transferBuf, info);
  738.         if (lasttime != -1)
  739.         {
  740.             timeDiff = (dmInfo->time.tv_sec - lastsec) * TIME_GRANULARITY;
  741.             timeDiff += (int)(dmInfo->time.tv_usec - lasttime + 500) /
  742.                 (1000000 / TIME_GRANULARITY);
  743.             if (timeDiff >= TIME_ARRAY_SIZE)
  744.             timeDiff = TIME_ARRAY_SIZE-1;
  745.             time_array[timeDiff] += 1;
  746.         }
  747.         lasttime = dmInfo->time.tv_usec;
  748.         lastsec = dmInfo->time.tv_sec;
  749.     }
  750.  
  751.     if (!fast)
  752.  
  753.  
  754.     /* do some graphics here - this is part of the main loop */
  755.     getframe = (ulong *)dataPtr;
  756.     if (leftmousedown) {
  757.        x = (short)(getvaluator(MOUSEX) - orgx - (xsize*pixscale)/2);
  758.            y = (short)(getvaluator(MOUSEY)-orgy-(ysize*yzoommult*pixscale)/2);
  759.     }/* endif leftmousedown */
  760.     draw_scene(x,y);
  761.  
  762.     vlPutFree(svr, transferBuf);
  763.     frameCount++;
  764.     if (framenumber >= totalCount)
  765.         exitcapture();
  766.     break;
  767.     case VLTransferFailed:
  768.     printf("VL transfer failed\n");    
  769.     exitcapture(); 
  770.     break;
  771.     default:
  772.     printf("Got Event %d\n", ev->reason);
  773.     break;
  774.     }
  775. }
  776.  
  777.  
  778. void
  779. ProcessGlEvent(int fd, void *win)
  780. {
  781.     static short val;
  782.     int loop;
  783.     long device;
  784.  
  785.       while(qtest()){
  786.        device = qread(&val);
  787.        switch (device)
  788.        {
  789. /* start rotate image cases here */
  790.     case INPUTCHANGE:
  791.             active = val;
  792.             if (val);
  793.             break;
  794.     case LEFTMOUSE:
  795.             leftmousedown = val; /* 1 if mouse button down */
  796.             break;
  797.     case MIDDLEMOUSE:
  798.             switch (backcolor)
  799.             {
  800.             case 1:
  801.                 RGBcolor(0, 0, 255);
  802.                 break;
  803.             case 2:
  804.                 RGBcolor(0, 255, 0);
  805.                 break;
  806.             case 3:
  807.                 RGBcolor(255, 0, 0);
  808.                 break;
  809.             case 4:
  810.                 RGBcolor(255, 255, 255);
  811.                 break;
  812.             default:
  813.             case 0:
  814.                 RGBcolor(0, 0, 0);
  815.                 break;
  816.             }
  817.             clear();
  818.             break;
  819.     case RIGHTMOUSE:
  820.             if (val) {
  821.             switch (dopup(menu)) {
  822.                 case 1:
  823.                 alpha = 0xff000000;
  824.                 doalpha = 0;
  825.                 break;
  826.                 case 2:
  827.                 alpha = 0x3f000000;
  828.                 doalpha = 1;
  829.                 break;
  830.                 case 3:
  831.                 alpha = 0x0f000000;
  832.                 doalpha = 1;
  833.                 break;                
  834.                 case 4:
  835.                 x += xsize*pixscale/2;
  836.                 y += ysize*pixscale/2;
  837.                 pixscale = 1;
  838.                 x -= xsize/2;
  839.                 y -= ysize/2;
  840.                 rzoom = 1;
  841.                 break;
  842.                 case 5:
  843.                 if (effecttype == 0){
  844.                 x += xsize*pixscale/2;
  845.                 y += ysize*pixscale/2;
  846.                 pixscale = 2;
  847.                 x -= xsize*pixscale/2;
  848.                 y -= ysize*pixscale/2;
  849.                 rzoom = 2;
  850.                 }else
  851.                 printf("Zoom in paint mode only\n\a");
  852.                 break;
  853.                 case 6:
  854.                 if (effecttype == 0){
  855.                 x += xsize*pixscale/2;
  856.                 y += ysize*pixscale/2;
  857.                 pixscale = 4;
  858.                 x -= xsize*pixscale/2;
  859.                 y -= ysize*pixscale/2;
  860.                 rzoom = 4;
  861.                 }else
  862.                 printf("Zoom in paint mode only\n\a");
  863.                 break;                
  864.                 case 7:
  865.                 drawcolors = 0;
  866.                 break;                
  867.                 case 8:
  868.                 drawcolors = 1;
  869.                 break;
  870.                 case 9:
  871.                 drawcolors = 2;
  872.                 break;
  873.                 case 10:
  874.                 switch (backcolor)
  875.                 {
  876.                 case 1:
  877.                     RGBcolor(0, 0, 255);
  878.                     break;
  879.                 case 2:
  880.                     RGBcolor(0, 255, 0);
  881.                     break;
  882.                 case 3:
  883.                     RGBcolor(255, 0, 0);
  884.                     break;
  885.                 case 4:
  886.                     RGBcolor(255, 255, 255);
  887.                     break;
  888.                 default:
  889.                 case 0:
  890.                     RGBcolor(0, 0, 0);
  891.                     break;
  892.                 }
  893.                 clear();
  894.                 effecttype = 0;
  895.                 break;
  896.                 case 11:
  897.                 x += xsize*pixscale/2;
  898.                 y += ysize*pixscale/2;
  899.                 pixscale = 1;
  900.                 x -= xsize/2;
  901.                 y -= ysize/2;
  902.                 rectzoom(1.0,1.0);
  903.                 switch (backcolor)
  904.                 {
  905.                 case 1:
  906.                     RGBcolor(0, 0, 255);
  907.                     break;
  908.                 case 2:
  909.                     RGBcolor(0, 255, 0);
  910.                     break;
  911.                 case 3:
  912.                     RGBcolor(255, 0, 0);
  913.                     break;
  914.                 case 4:
  915.                     RGBcolor(255, 255, 255);
  916.                     break;
  917.                 default:
  918.                 case 0:
  919.                     RGBcolor(0, 0, 0);
  920.                     break;
  921.                 }
  922.                 clear();
  923.                 effecttype = 1;
  924.                 break;
  925.                 case 12: 
  926.                 backcolor = backcolor + 1;
  927.                 if (backcolor > 4)
  928.                   backcolor = 0;
  929.                 switch (backcolor)
  930.                 {
  931.                 case 1:
  932.                     RGBcolor(0, 0, 255);
  933.                     break;
  934.                 case 2:
  935.                     RGBcolor(0, 255, 0);
  936.                     break;
  937.                 case 3:
  938.                     RGBcolor(255, 0, 0);
  939.                     break;
  940.                 case 4:
  941.                     RGBcolor(255, 255, 255);
  942.                     break;
  943.                 default:
  944.                 case 0:
  945.                     RGBcolor(0, 0, 0);
  946.                     break;
  947.                 }
  948.                 clear();
  949.                 break;
  950.                 case 13:
  951.                 gexit(); /* add for graphics */
  952.                 exitcapture();
  953.                 break;
  954.             }
  955.             }
  956.             break;
  957.     case REDRAW:
  958.         reshapeviewport();
  959.         getorigin(&orgx, &orgy);
  960.         break;
  961.     case DKEY :
  962.         if (val == 1) {
  963.         if (double_buffer = 1 - double_buffer) {
  964.             doublebuffer();
  965.             Debug("double buffer mode\n");
  966.         }
  967.         else {
  968.             singlebuffer();
  969.             Debug("single buffer mode\n");
  970.         }
  971.         gconfig();
  972.         }
  973.         break;
  974.     case CKEY:
  975.         if (val)
  976.         {
  977.           backcolor = backcolor + 1;
  978.           if (backcolor > 4)
  979.             backcolor = 0;
  980.           switch (backcolor)
  981.           {
  982.           case 1:
  983.             RGBcolor(0, 0, 255);
  984.             break;
  985.           case 2:
  986.             RGBcolor(0, 255, 0);
  987.             break;
  988.           case 3:
  989.             RGBcolor(255, 0, 0);
  990.             break;
  991.           case 4:
  992.             RGBcolor(255, 255, 255);
  993.             break;
  994.           default:
  995.           case 0:
  996.             RGBcolor(0, 0, 0);
  997.             break;
  998.           }
  999.           clear();
  1000.         }/* if val */
  1001.         break;
  1002.  
  1003.     /* Quit capture */
  1004.     case QKEY :
  1005.         if (val != 1){
  1006.         break;
  1007.         }
  1008.  
  1009.     case ESCKEY:
  1010.     case WINSHUT:
  1011.     case WINQUIT:
  1012.         gexit(); /* add for graphics */
  1013.         exitcapture();
  1014.         break;
  1015.         } /* end switch */
  1016.     } /* end if qtest */
  1017. }/* end procedure */
  1018.  
  1019. void
  1020. exitcapture()
  1021. {
  1022.     int loop, j;
  1023.  
  1024.     /* End the data transfer */
  1025.     vlEndTransfer(vlSvr, vlPath);
  1026.  
  1027.     /* Disassociate the ring buffer from the path */
  1028.     vlDeregisterBuffer(vlSvr, vlPath, drn, transferBuf);
  1029.  
  1030.     /* Destroy the path, free the memory it used */
  1031.     vlDestroyPath(vlSvr,vlPath);
  1032.     
  1033.     /* Destroy the ring buffer, free the memory it used */
  1034.     vlDestroyBuffer(vlSvr, transferBuf);
  1035.  
  1036.     /* Disconnect from the daemon */
  1037.     vlCloseVideo(vlSvr);
  1038.  
  1039.     /* Print the time stamps from the captured frames */
  1040.     if (time_on)
  1041.         for (loop = 0; loop < TIME_ARRAY_SIZE; ) {
  1042.         printf("%3d: ", loop);
  1043.         for (j = 0; j < 5; j++)
  1044.             printf("\t%d", time_array[loop++]);
  1045.         printf("\n");
  1046.         }
  1047.  
  1048.     exit(0);
  1049. }
  1050.  
  1051. /* === */
  1052.